package site.tuluan.sp4j.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.time.DateUtils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    /**
     * 生成token
     * @param payLoadMap 载荷
     * @param secret 密钥
     * @return token
     */
    public static String geneToken(Map<String, ?> payLoadMap, String secret) {
        return geneToken(payLoadMap, secret, null);
    }

    /**
     * 生成token
     * @param payLoadMap 载荷
     * @param secret 密钥
     * @param minutes 有效时间 单位：分钟 不设置就不限制
     * @return token
     */
    public static String geneToken(Map<String, ?> payLoadMap, String secret, Integer minutes) {
        JWTCreator.Builder builder = JWT.create().withPayload(payLoadMap);
        if (minutes != null) {
            builder.withExpiresAt(DateUtils.addMinutes(new Date(), minutes));
        }
        return builder.sign(Algorithm.HMAC512(secret));
    }

    /**
     * 验证token
     * @param token token
     * @param secret 密钥
     * @return 是否通过
     */
    public static boolean verifyToken(String token, String secret) {
        try {
            getDecodeJWT(token, secret);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取载荷里某个声明的值
     * @param token token
     * @param key key
     * @return value
     */
    public static String getClaimStr(String token, String key) {
        return JWT.decode(token).getClaim(key).asString();
    }

    /**
     * 获取载荷
     * @param token token
     * @return 载荷
     */
    public static String getPayLoad(String token) {
        DecodedJWT jwt = JWT.decode(token);

        return new String(Base64.getDecoder().decode(jwt.getPayload()), StandardCharsets.UTF_8);
    }

    /**
     * 获取载荷
     * @param token token
     * @param secret 密钥
     * @return 载荷
     */
    public static String getPayLoad(String token, String secret) {
        DecodedJWT jwt = getDecodeJWT(token, secret);

        return new String(Base64.getDecoder().decode(jwt.getPayload()), StandardCharsets.UTF_8);
    }

    private static DecodedJWT getDecodeJWT(String token, String secret) {
        return JWT.require(Algorithm.HMAC512(secret)).build().verify(token);
    }
}
